/**
 * Alibaba.com.cn Inc.
 * Copyright (c) 2004-2021 All Rights Reserved.
 */
package com.starlink.common.strategy.paynotify;

import com.starlink.common.enums.OrderRefundEnum;
import com.starlink.common.enums.OrderStatusEnum;
import com.starlink.common.enums.OrderTypeEnum;
import com.starlink.common.strategy.IPayNotify;
import com.starlink.context.SessionContext;
import com.starlink.mapper.MallRefundsMapper;
import com.starlink.mapper.ShoppingCartOrderMapper;
import com.starlink.model.domain.MallBooksOrderDO;
import com.starlink.model.domain.MallRefundsDO;
import com.starlink.model.domain.ShoppingCartOrderDO;
import com.starlink.model.request.MallPaymentRequest;
import com.starlink.model.request.MallRefundPriceRequest;
import com.starlink.model.request.ShoppingCartOrderRequest;
import com.starlink.model.request.mall.WechatPay;
import com.starlink.model.request.mall.WechatRefund;
import com.starlink.model.vo.mall.MallOrderCarCancelListVO;
import com.starlink.service.*;
import com.starlink.utils.IRedisCacheService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.starlink.common.enums.OperationTypeEnum.ADMIN_REFUND_PRICE;
import static com.starlink.common.enums.OrderStatusEnum.*;
import static com.starlink.common.enums.OrderTypeEnum.BOOK;
import static com.starlink.common.enums.OrderTypeEnum.RIM;
import static com.starlink.common.enums.RedisHashKeyEnum.CAR_ORDER_PRODUCT_IDS;

/**
 * @author zhanghong
 * @version CartPayNotify.java, v 0.1 2024/4/11 23:02 下午 CartPayNotify Exp $$
 */
@Slf4j
@Component
public class CartPayNotify implements IPayNotify {
    @Autowired
    private ShoppingCartOrderService cartOrderService;
    @Autowired
    private MallPaymentService paymentService;
    @Autowired
    private ShoppingCartDetailService cartDetailService;
    @Autowired
    private ShoppingCartOrderMapper cartOrderManager;
    @Autowired
    private ShoppingCartOrderDetailsService cartOrderDetailsService;
    @Autowired
    private MallBooksSpecificationService specificationService;
    @Autowired
    private MallPeripherySpecificationService peripherySpecificationService;
    @Autowired
    private MallRefundPriceService refundPriceService;
    @Autowired
    private MallRefundsMapper refundsMapper;
    @Autowired
    private IRedisCacheService redisCacheService;

    @Override
    public boolean supports(Integer orderType) {
        return orderType.equals(OrderTypeEnum.CART.getType());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handle(WechatPay wechatPay) {
        Long orderId = Long.valueOf(wechatPay.getOrderId());
        String weChatOrderId = wechatPay.getWeChatOrderId();
        String payType = wechatPay.getPayType();
        String amount = wechatPay.getAmount();
        Date paymentDate = wechatPay.getPaymentDate();
        List<Long> carOrderIds = redisCacheService.hashGet(CAR_ORDER_PRODUCT_IDS.name(),orderId.toString());
        //改订单状态
        ShoppingCartOrderDO orderDO = cartOrderService.lambdaQuery().eq(ShoppingCartOrderDO::getId, orderId).one();
        if (!WAIT_FREE.getType().equals(orderDO.getStatus())) {
            ShoppingCartOrderRequest cartOrderRequest = new ShoppingCartOrderRequest();
            cartOrderRequest.setId(orderId);
            cartOrderRequest.setWxOrderNum(weChatOrderId);
            cartOrderRequest.setStatus(OrderStatusEnum.WAIT_FREE.getType().toString());
            cartOrderRequest.setUpdateTime(new Date());
            cartOrderService.updateByKey(cartOrderRequest);
            cartDetailService.batchDeleted(carOrderIds);//移除结算商品
        }
        //添加支付记录
        MallPaymentRequest mallPaymentRequest = new MallPaymentRequest();
        mallPaymentRequest.setOrderId(orderId);
        mallPaymentRequest.setWxOrderNum(weChatOrderId);
        mallPaymentRequest.setPaymentDate(paymentDate);
        mallPaymentRequest.setPaymentMethod(payType);
        mallPaymentRequest.setAmount(new BigDecimal(amount));
        mallPaymentRequest.setCreateTime(new Date());
        String wxOrderNum = paymentService.selectWxOrderNumByOrderId(orderId);
        if (StringUtils.isEmpty(wxOrderNum) && !weChatOrderId.equals(wxOrderNum)){
            paymentService.add(mallPaymentRequest);
        }

    }

    @Override
    public void refundHandle(WechatRefund wechatPay) {//暂未考虑购物车订单分多次售后的情况
        log.info("退款回调传参->{}",wechatPay);
        Long orderId = wechatPay.getOrderId();
        Long loginAccountId = wechatPay.getUserId();
        String orderNum = wechatPay.getOrderNum();
        MallRefundPriceRequest priceRequest = new MallRefundPriceRequest();
        //归还库存
        if (ADMIN_REFUND_PRICE.getType().equals(wechatPay.getOperationType())){//通过售后记录查询商品ID及数量等信息
            Long refundId = refundsMapper.selectIdByOrderId(wechatPay.getOrderId());
            priceRequest.setRefundId(refundId);
            //修改订单状态
            cartOrderManager.updateStatus(orderId,BEFOR_SALE.getType().toString(),new Date());
            List<MallOrderCarCancelListVO> list = cartOrderDetailsService.selectSpecificationId(orderId);
            list.stream().forEach(item->{
                Integer itemQuantity = item.getQuantity();
                Integer articlesCategory = item.getArticlesCategory();
                Long specificationId = item.getSpecificationId();
                Long articlesId = item.getArticlesId();
                if (BOOK.getType().equals(articlesCategory)){
                    //归还库存
                    Map<String, Long> map = new HashMap<>();
                    map.put("specificationId", specificationId);
                    map.put("quantity",Long.valueOf(itemQuantity));
                    specificationService.addQuantity(map);
                }
                if (RIM.getType().equals(articlesCategory)){
                    //归还库存
                    Map<String, Long> map = new HashMap<>();
                    map.put("specificationId", specificationId);
                    map.put("quantity",Long.valueOf(itemQuantity));
                    peripherySpecificationService.addQuantity(map);
                }
                cartOrderDetailsService.updateIsRefunds(orderId,articlesId);
            });
            //修改售后状态
            MallRefundsDO refundsDO = new MallRefundsDO();
            refundsDO.setOrderId(orderId);
            refundsDO.setStatus(OrderRefundEnum.WAN_CHENG.getType());
            refundsDO.setAdminId(loginAccountId);
            refundsDO.setUpdateTime(new Date());
            refundsDO.setUpdateUser(loginAccountId);
            refundsMapper.updateByOrderId(refundsDO);
        }else {//通过传递参数来恢复库存
            //修改订单状态
            cartOrderManager.updateStatus(orderId,CANCEL.getType().toString(),new Date());
            //商品ID:数量
            Map<Long, Integer> carData = wechatPay.getCarData();
            carData.forEach((key,value)->{
                MallOrderCarCancelListVO item = cartOrderDetailsService.selectDataInfoByAId(key,orderId);
                Integer articlesCategory = item.getArticlesCategory();
                Long specificationId = item.getSpecificationId();
                if (BOOK.getType().equals(articlesCategory)){
                    //归还库存
                    Map<String, Long> map = new HashMap<>();
                    map.put("specificationId", specificationId);
                    map.put("quantity",Long.valueOf(value));
                    specificationService.addQuantity(map);
                }
                if (RIM.getType().equals(articlesCategory)){
                    //归还库存
                    Map<String, Long> map = new HashMap<>();
                    map.put("specificationId", specificationId);
                    map.put("quantity",Long.valueOf(value));
                    peripherySpecificationService.addQuantity(map);
                }
            });
        }
        //添加退款记录
        priceRequest.setRefundNum(wechatPay.getRefundNum());
        priceRequest.setWxRefundNum(wechatPay.getWxRefundNum());
        priceRequest.setOrderNum(wechatPay.getOrderNum());
        priceRequest.setRefundPrice(new BigDecimal(wechatPay.getAmount()));
        priceRequest.setRefundType(wechatPay.getRefundType());
        priceRequest.setRefundTime(new Date());
        priceRequest.setCreateTime(new Date());
        priceRequest.setCreateUser(loginAccountId);
        Integer count =  refundPriceService.selectCountByOrderId(orderNum);
        if (count==0){
            refundPriceService.add(priceRequest);
        }
    }
}
